package com.example.demo.utils;

import com.example.demo.domain.TextEntity;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;

import java.io.File;

/**
 * @author sdy
 * @description
 * @date 2025/9/13
 */
public class PdfBoxWatermarkUtils {

    public static void addTextWatermark(String inputFile, String outputFile, TextEntity watermarkText) {
        try(PDDocument document = Loader.loadPDF(new File(inputFile))) {

            PDType0Font font = PDType0Font.load(document, watermarkText.readFont());

            float spaceX = 200;
            float spaceY = 150;

            for (PDPage page : document.getPages()) {
                float height = page.getMediaBox().getHeight();
                float width = page.getMediaBox().getWidth();
                try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {

                    float startX = 50;
                    float startY = 50;

                    PDExtendedGraphicsState gs = new PDExtendedGraphicsState();
                    gs.setNonStrokingAlphaConstant(watermarkText.getOpacity());
                    contentStream.setGraphicsStateParameters(gs);

                    contentStream.setFont(font, watermarkText.getFontsize());
                    contentStream.setNonStrokingColor(watermarkText.getAwtColor());

                    float rotation = (float) Math.toRadians(watermarkText.getAngle());

                    int cols = (int) (width / spaceX) + 2;
                    int rows = (int) (height / spaceY) + 2;

                    for (int i = -1; i < rows; i++) {
                        for (int j = -1; j < cols; j++) {
                            float x = j * spaceX;
                            float y = i * spaceY;

                            contentStream.saveGraphicsState();

                            Matrix matrix = Matrix.getTranslateInstance(x, y)
                                    .multiply(Matrix.getRotateInstance(rotation, x, y));
                            contentStream.transform(matrix);

                            contentStream.beginText();
                            contentStream.showText(watermarkText.getText());
                            contentStream.endText();

                            contentStream.restoreGraphicsState();
                        }
                    }
                }
            }

            document.save(outputFile);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 添加图片水印（PDFBox 3.0.3 最新API）
     */
    public static void addImageWatermark(String inputPath, String outputPath,
                                         String imagePath, float opacity,
                                         float scale) {
        try (PDDocument document = Loader.loadPDF(new File(inputPath))) {
            // 加载图片
            PDImageXObject image = PDImageXObject.createFromFile(imagePath, document);

            // 计算缩放后尺寸
            int scaledWidth = (int) (image.getWidth() * scale);
            int scaledHeight = (int) (image.getHeight() * scale);

            for (PDPage page : document.getPages()) {
                PDRectangle mediaBox = page.getMediaBox();
                float pageWidth = mediaBox.getWidth();
                float pageHeight = mediaBox.getHeight();

                try (PDPageContentStream contentStream = new PDPageContentStream(
                        document, page, PDPageContentStream.AppendMode.APPEND, true)) {

                    // 设置透明度
                    PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState();
                    extendedGraphicsState.setNonStrokingAlphaConstant(opacity);
                    contentStream.setGraphicsStateParameters(extendedGraphicsState);

                    // 计算水印间距
                    float spacingX = scaledWidth * 2;
                    float spacingY = scaledHeight * 2;

                    // 计算网格数量
                    int cols = (int) (pageWidth / spacingX) + 2;
                    int rows = (int) (pageHeight / spacingY) + 2;

                    // 绘制图片水印
                    for (int i = -1; i < rows; i++) {
                        for (int j = -1; j < cols; j++) {
                            float x = j * spacingX;
                            float y = i * spacingY;
                            contentStream.drawImage(image, x, y, scaledWidth, scaledHeight);
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            document.save(outputPath);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String input = "/Users/sdy/Desktop/input.pdf";
        String output = "/Users/sdy/Desktop/output.pdf";

        TextEntity textEntity = new TextEntity("测试水印");
        textEntity.setFontsize(16f);
        textEntity.setAngle(45f);
        textEntity.setAwtColor(java.awt.Color.LIGHT_GRAY);
        textEntity.setOpacity(0.6f);

//        addTextWatermark(input, output, textEntity);

        addImageWatermark(input, output, "/Users/sdy/Documents/IdeaProjects/yeecoh/dy-tool/src/main/resources/image/spdb.png", 0.15f, 0.25f);
    }

}
